package com.by.toolkitspring.support;

import cn.hutool.core.date.LocalDateTimeUtil;
import cn.hutool.core.util.RandomUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson2.JSON;
import com.by.toolkit.consts.DatePatternConst;
import com.by.toolkit.consts.GlobalConst;
import lombok.*;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;

import java.time.LocalDateTime;
import java.util.Arrays;
import java.util.Map;
import java.util.function.Function;
import java.util.stream.Collectors;

@Slf4j
public class SerialNumSupport {

    public static final SerialNumSupport INSTANCE = new SerialNumSupport();

    private SerialNumSupport() {
    }

    public static String generateSerialNum(Long projectId, BizTypeEnum bizType) {
        if (BizTypeEnum.LIVE_CODE.equals(bizType)) {
            return "LIVE"
                    .concat(LocalDateTimeUtil.format(LocalDateTime.now(), DatePatternConst.DATE_STAMP))
                    .concat(StringUtils.leftPad(projectId.toString(), 4, GlobalConst.ZERO_STR))
                    .concat(StringUtils.leftPad(String.valueOf(RandomUtil.randomInt(1, 9999)), 4, GlobalConst.ZERO_STR));
        }
        return LocalDateTimeUtil.format(LocalDateTime.now(), DatePatternConst.DATE_TIME_STAMP)
                .concat(StringUtils.leftPad(projectId.toString(), 4, GlobalConst.ZERO_STR))
                .concat(StringUtils.leftPad(bizType.getCode().toString(), 3, GlobalConst.ZERO_STR))
                .concat(StringUtils.leftPad(String.valueOf(RandomUtil.randomInt(1, 9999)), 4, GlobalConst.ZERO_STR));
    }

    public static SerialNumInfo analysisSerialNum(String serialNum) {
        if (serialNum.startsWith("LIVE")) {
            return SerialNumInfo.builder()
                    .projectId(Long.parseLong(StringUtils.stripStart(StrUtil.sub(serialNum, 12, 16), GlobalConst.ZERO_STR)))
                    .bizType(BizTypeEnum.LIVE_CODE.getCode())
                    .build();
        }
        if (serialNum.length() < 25 || !StrUtil.isNumeric(serialNum)) {
            return null;
        }
        return SerialNumInfo.builder()
                .projectId(Long.parseLong(StringUtils.stripStart(StrUtil.sub(serialNum, 14, 18), GlobalConst.ZERO_STR)))
                .bizType(Integer.parseInt(StringUtils.stripStart(StrUtil.sub(serialNum, 18, 21), GlobalConst.ZERO_STR)))
                .build();
    }

    public static void main(String[] args) {
        String serialNum = generateSerialNum(1L, BizTypeEnum.LIVE_CODE);
        System.out.println(serialNum);
        System.out.println(JSON.toJSONString(analysisSerialNum(serialNum)));
    }

    @Data
    @Builder
    @NoArgsConstructor
    @AllArgsConstructor
    public static class SerialNumInfo {

        private Long projectId;

        private Integer bizType;

    }

    @Getter
    @AllArgsConstructor
    public enum BizTypeEnum {

        ORDER(1, "订单"),
        REFUND_ORDER(2, "退款订单"),
        OPERATION_REWARD_ORDER(3, "运营奖励订单"),
        PHYSICAL_ORDER(4, "实物订单"),
        SELF_OPERATION_LOGISTIC_NO(5, "自营物流单号"),
        LIVE_CODE(6, "直播编码"),
        ;

        private Integer code;
        private String desc;

        private static final Map<Integer, BizTypeEnum> MAP = Arrays.stream(BizTypeEnum.values())
                .collect(Collectors.toMap(BizTypeEnum::getCode, Function.identity()));


        public static BizTypeEnum resolve(Integer code) {
            return MAP.get(code);
        }

    }


}
